package cn.com.jcoo;

import cn.com.jcoo.exception.ISysError;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.http.HttpStatus;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * 统一响应内容对象
 *
 * @param <T> 响应数据内容类型
 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
public class Res<T> implements Serializable {
    /**
     * 响应码
     */
    @Schema(description = "响应码")
    private int code;
    /**
     * 响应提示信息
     */
    @Schema(description = "响应提示信息")
    private String message;
    /**
     * 响应数据内容
     */
    @Schema(description = "响应数据内容")
    private T data;
    /**
     * 响应异常标记
     */
    @Schema(description = "响应异常标记")
    private Boolean exception;

    @Schema(description = "操作成功标记： code == 200")
    public boolean isOk() {
        return code == HttpStatus.OK.value();
    }

    public Map<String, Object> toMap() {
        Map<String, Object> map = new HashMap<>(3);
        map.put("code", getCode());
        map.put("message", getMessage());
        map.put("data", getData());
        return map;
    }

    public Res(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public Res(Throwable e) {
        this.exception = Boolean.TRUE;
        if (e instanceof ISysError sysError) {
            this.code = sysError.getCode();
            this.message = sysError.getMessage();
        } else {
            this.code = ISysError.DEFAULT_CODE;
            this.message = "系统异常";
        }
    }

    public static Res<Void> ok() {
        return new Res<>(HttpStatus.OK.value(), "操作成功", null);
    }

    public static <T> Res<T> ok(T data) {
        return new Res<>(HttpStatus.OK.value(), "操作成功", data);
    }

    public static <T> Res<T> ok(String message, T data) {
        return new Res<>(HttpStatus.OK.value(), message, data);
    }

    public static <T> Res<T> error() {
        return new Res<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "操作失败", null);
    }

    public static <T> Res<T> error(T data) {
        return new Res<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "操作失败", data);
    }

    public static <T> Res<T> error(String message, T data) {
        return new Res<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), message, data);
    }

    public static <T> Res<T> error(Throwable e) {
        return new Res<>(e);
    }

}

